﻿/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

Copyright (C) 2005-2009  Cyber Sinh (http://www.luminescence-software.org/)
*/

using System;
using System.IO;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

namespace Luminescence.Xiph
{
  /// <summary>
  /// Classe de lecture / écriture des images dans les fichiers FLAC.
  /// </summary>
  public class ID3PictureFrame
  {
    /// <summary>
    /// Constructeur de la classe ID3Picture.
    /// </summary>
    /// <param name="data">Données METADATA_BLOCK_PICTURE sous la forme d'un tableau d'octets</param>
    public ID3PictureFrame(byte[] data)
    {
      MemoryStream ms = new MemoryStream(data, 0, data.Length, false);
      BinaryReader br = new BinaryReader(ms);
      byte[] buffer;

      PictureType = (ID3PictureType)br.ReadBigEndianInt32();

      int mimeSize = br.ReadBigEndianInt32();
      ms.Position += mimeSize;

      int descSize = br.ReadBigEndianInt32();
      if (descSize > 0)
      {
        buffer = br.ReadBytes(descSize);
        UTF8Encoding utf8 = new UTF8Encoding();
        Description = utf8.GetString(buffer, 0, buffer.Length);
      }

      ms.Position += 16;
      int pictSize = br.ReadBigEndianInt32();
      buffer = br.ReadBytes(pictSize);

      // New for Avian Play (we use bitmap instead of bitmapframe)
      Picture = new Bitmap(new MemoryStream(buffer, 0, buffer.Length));
      
      //BitmapDecoder bd = BitmapDecoder.Create(new MemoryStream(buffer, 0, buffer.Length), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnDemand);
      //Picture = bd.Frames[0];
    }

    /// <summary>
    /// Constructeur de la classe ID3Picture.
    /// </summary>
    /// <param name="data">Bitmap constituant l'image</param>
    public ID3PictureFrame(Bitmap data)
    {
      PictureType = ID3PictureType.FrontCover;
      Picture = data;
    }

    /// <summary>
    /// Constructeur de la classe ID3Picture.
    /// </summary>
    /// <param name="data">Bitmap constituant l'image</param>
    /// <param name="pictType">Type d'image selon la norme ID3v2 (frame APIC)</param>
    public ID3PictureFrame(Bitmap data, ID3PictureType pictType)
    {
      Picture = data;
      PictureType = pictType;
    }

    /// <summary>
    /// Type d'image selon la norme ID3v2 (frame APIC).
    /// </summary>
    public ID3PictureType PictureType { get; set; }

    /// <summary>
    /// Description de l'image.
    /// </summary>
    public string Description { get; set; }

    /// <summary>
    /// Bitmap constituant l'image.
    /// </summary>
    public Bitmap Picture { get; set; }

    /// <summary>
    /// Retourne les données de l'image à la norme ID3 (frame APIC).
    /// </summary>
    /// <returns>Données de la frame sous la forme d'un tableau d'octets</returns>
    public byte[] ToApicFrame()
    {
      // THIS IS NOT IMPLEMENTED SINCE AVIAN PLAY HAD TO CONVERT A BITMAPFRAME TO BITMAP FOR CF COMPATIBILITY
      return new byte[0];

      //MemoryStream ms = new MemoryStream();

      //byte[] buffer = ((int)PictureType).ToBigEndian();
      //ms.Write(buffer, 0, buffer.Length);

      //ASCIIEncoding ascii = new ASCIIEncoding();
      //byte[] binMime = ascii.GetBytes(Picture.Decoder.CodecInfo.MimeTypes);
      //buffer = binMime.Length.ToBigEndian();
      //ms.Write(buffer, 0, buffer.Length);
      //ms.Write(binMime, 0, binMime.Length);

      //if (String.IsNullOrEmpty(Description))
      //{
      //  ms.Write(new byte[] { 0, 0, 0, 0 }, 0, 4);
      //}
      //else
      //{
      //  UTF8Encoding utf8 = new UTF8Encoding();
      //  byte[] binDesc = utf8.GetBytes(Description);
      //  buffer = binDesc.Length.ToBigEndian();
      //  ms.Write(buffer, 0, buffer.Length);
      //  ms.Write(binMime, 0, binMime.Length);
      //}

      //buffer = Picture.PixelWidth.ToBigEndian();
      //ms.Write(buffer, 0, buffer.Length);

      //buffer = Picture.PixelHeight.ToBigEndian();
      //ms.Write(buffer, 0, buffer.Length);

      //int bitsPerPixel = Picture.Format.BitsPerPixel;
      //int nbIndexedColors = 0;
      //if (Picture.Palette != null)
      //  nbIndexedColors = Picture.Palette.Colors.Count;

      //buffer = bitsPerPixel.ToBigEndian();
      //ms.Write(buffer, 0, buffer.Length);

      //buffer = nbIndexedColors.ToBigEndian();
      //ms.Write(buffer, 0, buffer.Length);

      //MemoryStream image = new MemoryStream();
      //BitmapEncoder be = BitmapEncoder.Create(Picture.Decoder.CodecInfo.ContainerFormat);
      //be.Frames.Add(Picture);
      //be.Save(image);
      //byte[] binPicture = image.ToArray();
      //buffer = binPicture.Length.ToBigEndian();
      //ms.Write(buffer, 0, buffer.Length);
      //ms.Write(binPicture, 0, binPicture.Length);

      //return ms.ToArray();
    }
  }
}